package cn.mw.cmdb.controller;

import cn.hutool.core.date.DateUtil;
import cn.mw.cmdb.entity.InventoryWorkAssets;
import cn.mw.cmdb.entity.InventoryWorkInfo;
import cn.mw.cmdb.entity.dto.InventoryHistoryCountDTO;
import cn.mw.cmdb.entity.dto.InventoryHistoryDetailsDTO;
import cn.mw.cmdb.param.InventoryAssetsIdsParam;
import cn.mw.cmdb.param.InventoryIdsParam;
import cn.mw.cmdb.param.InventorySearchParam;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.InventoryWorkAssetsServiceImpl;
import cn.mw.cmdb.service.impl.InventoryWorkInfoServiceImpl;
import cn.mw.cmdb.util.Pinyin4jUtil;
import cn.mw.cmdb.util.QrCodeUtil;
import cn.mw.cmdb.util.UUIDUtils;
import cn.mw.cmdb.view.ViewConvertContext;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.components.mongodb.exception.BusinessException;
import cn.mw.components.mongodb.page.MWPage;
import cn.mw.microMonitorCommon.api.common.BaseApiService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.util.DateUtils;
import cn.mw.microMonitorCommon.util.FileNameCheckUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;

import static cn.mw.microMonitorCommon.constant.DateConstant.NORM_DATETIME;

/**
 * @Author shenwenyi
 * @Date 2024/4/26 15:46
 * @PackageName:cn.mw.cmdb.controller
 * @ClassName: InventoryController
 * @Description: TODD
 * @Version 1.0
 */
@RequestMapping("/inventory")
@Controller
@Tag(name = "盘点管理")
@Slf4j
public class InventoryController extends BaseApiService {
    private CmdbServiceManage cmdbServiceManage;
    private ViewManager viewManager;
    private MessageSource messageSource;

    //文件上传路径
    @Value("${file.url}")
    private String filePath;
    //logo上传目录
    static final String MODULE = "inventory-upload";

    static final String URL = "cmdb_download";

    public InventoryController(CmdbServiceManage cmdbServiceManage, ViewManager viewManager, MessageSource messageSource) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.viewManager = viewManager;
        this.messageSource = messageSource;
    }

    @PostMapping("/saveInventoryWork")
    @Operation(summary = "新增盘点任务")
    @ResponseBody
    public ResponseBase<Void> saveInventoryWork(@RequestBody @Valid InventoryWorkInfo info) throws Exception {
        Date now = DateUtils.date();
        if(now.after(info.getPlannedStartTime())){
            return setResultFail(messageSource.getMessage("plan-time-before-now-error",new Object[]{DateUtils.format(now,NORM_DATETIME)},LocaleContextHolder.getLocale()));
        }
        if(info.getPlannedStartTime().after(info.getPlannedEndTime())){
            return setResultFail(messageSource.getMessage("plan-start-time-after-end-time",null,LocaleContextHolder.getLocale()));
        }
        cmdbServiceManage.service(info, ServiceAction.add);
        return setResultSuccess();
    }

    @PostMapping("/queryInventoryWorkPage")
    @Operation(summary = "盘点列表")
    @ResponseBody
    public ResponseBase queryInventoryWorkPage(@RequestBody InventorySearchParam searchParam) throws Exception {
        List<InventoryWorkInfo> ret = (List<InventoryWorkInfo>) cmdbServiceManage.service(searchParam, ServiceAction.list);
        Object pageRet = viewManager.getListViewObject(ret, InventoryWorkInfo.class, searchParam, new ViewConvertContext());
        return setResultSuccess(pageRet);
    }

    @PostMapping("/updateInventoryWork")
    @Operation(summary = "修改盘点")
    @ResponseBody
    public ResponseBase updateInventoryWork(@RequestBody InventoryWorkInfo info) throws Exception {
        cmdbServiceManage.service(info, ServiceAction.update);
        return setResultSuccess();
    }

    @PostMapping("/queryInventoryWorkById")
    @ResponseBody
    @Operation(summary = "查看盘点信息")
    public ResponseBase queryInventoryWorkById(@RequestBody InventorySearchParam param) throws Exception {
        Object o = cmdbServiceManage.service(param, ServiceAction.select);
        return setResultSuccess(o);
    }

    @PostMapping("/qrCode")
    @ResponseBody
    @Operation(summary = "查看盘点二维码")
    public ResponseBase queryQrCode(@RequestBody InventoryWorkInfo info) throws Exception {
        InventoryWorkInfo inventoryWork = (InventoryWorkInfo) cmdbServiceManage.service(info, ServiceAction.select);
        String qrCodeBase64 = QrCodeUtil.createQrCodeBase64(inventoryWork.getId(), 150, 150);
        return setResultSuccess(qrCodeBase64);
    }

//    @PostMapping("/qrCode")
//    @ResponseBody
//    @Operation(summary = "查看盘点二维码")
//    public ResponseBase downloadQrCode(@RequestBody InventoryWorkInfo info) throws Exception{
//        InventoryWorkInfo inventoryWork =(InventoryWorkInfo) cmdbServiceManage.service(info, ServiceAction.select);
//        String qrCodeBase64 = QrCodeUtil.createQrCodeBase64(inventoryWork.getId(), 150, 150);
//        return setResultSuccess(qrCodeBase64);
//    }

    @PostMapping("/selfInventory")
    @ResponseBody
    @Operation(summary = "我的盘点")
    public ResponseBase selfInventory(@RequestBody InventorySearchParam param) throws Exception {
        InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
        List ret = modelService.selfInventory(param);
        Object pageRet = viewManager.getListViewObject(ret, InventoryWorkInfo.class, param, new ViewConvertContext());
        return setResultSuccess(pageRet);
    }

    @PostMapping("/submit")
    @ResponseBody
    @Operation(summary = "我的盘点(提交)")
    public ResponseBase submit(@RequestBody List<InventoryWorkAssets> workAssetsList) throws Exception {
        InventoryWorkAssetsServiceImpl modelService = (InventoryWorkAssetsServiceImpl) cmdbServiceManage.getModelService(InventoryWorkAssetsServiceImpl.ID);
        modelService.submit(workAssetsList);
        return setResultSuccess();
    }

    @PostMapping("/addWorkAsset")
    @ResponseBody
    @Operation(summary = "盘点关联资产 添加")
    public ResponseBase addWorkAsset(@RequestBody InventoryWorkAssets workAssets) throws Exception {
        cmdbServiceManage.service(workAssets, ServiceAction.add);
        return setResultSuccess();
    }

    @PostMapping("/delWorkAsset")
    @ResponseBody
    @Operation(summary = "盘点关联资产 删除")
    public ResponseBase delWorkAsset(@RequestBody InventoryAssetsIdsParam param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.batchRemove);
        return setResultSuccess();
    }


    @PostMapping("/startInventory")
    @ResponseBody
    @Operation(summary = "开始盘点")
    public ResponseBase startInventory(@RequestBody InventoryAssetsIdsParam param) throws Exception {
        InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
        modelService.startInventory(param);
        return setResultSuccess();
    }

    @PostMapping("/inventoryHistory")
    @ResponseBody
    @Operation(summary = "盘点历史")
    public ResponseBase inventoryHistory(@RequestBody InventorySearchParam param) throws Exception {
        InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
        MWPage page = modelService.inventoryHistory(param);
        return setResultSuccess(page);
    }

    @PostMapping("/delInventory")
    @ResponseBody
    @Operation(summary = "删除盘点任务")
    public ResponseBase delInventoryWork(@RequestBody InventoryIdsParam param) throws Exception {
        try {
            cmdbServiceManage.service(param, ServiceAction.batchRemove);
            InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
            return setResultSuccess(modelService.delInventoryWork(param));
        }catch (Exception e){
            if(e instanceof BusinessException){
                return setResultFail(((BusinessException) e).getMessageKey());
            }else{
                return setResultFail();
            }
        }
    }

    @PostMapping("/inventoryHistoryDetails")
    @ResponseBody
    @Operation(summary = "盘点历史详情")
    public ResponseBase workAssetDetails(@RequestBody InventorySearchParam param) throws Exception {
        InventoryWorkAssetsServiceImpl service = (InventoryWorkAssetsServiceImpl)cmdbServiceManage.getModelService(InventoryWorkAssetsServiceImpl.ID);
        InventoryHistoryDetailsDTO dto = service.historyDetails(param);
        return setResultSuccess(dto);
    }

    @PostMapping("/inventoryHistoryCount")
    @ResponseBody
    @Operation(summary = "盘点历史数量")
    public ResponseBase inventoryHistoryCount() throws Exception {
        InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
        List<InventoryHistoryCountDTO> dto = modelService.inventoryHistoryCount();
        return setResultSuccess(dto);
    }

    @PostMapping("/upload/create")
    @ResponseBody
    @Operation(summary = "文件上传")
    public ResponseBase uploadLogo(@RequestParam("file") MultipartFile multipartFile) {
        if (multipartFile.isEmpty()) {
            return setResultFail("文件为空");
        }
        //获取文件名
        String fileName = multipartFile.getOriginalFilename();
        Pinyin4jUtil pinyin4jUtil=new Pinyin4jUtil();
        fileName= pinyin4jUtil.getStringPinYin(fileName);
        boolean validFileName = FileNameCheckUtils.isValidFileName(fileName);
        if(!validFileName){
            return setResultFail();
        }
        //文件重命名，防止重复
        fileName = UUIDUtils.getUUID() + fileName;
        //设置放到数据库字段的值
        //获取当前月份
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String uploadUrl= URL + File.separator + MODULE + File.separator +yyyyMM+File.separator+ fileName;
        return setResultSuccess(uploadUrl);
    }

    @PostMapping("/getInventoryWorkState")
    @ResponseBody
    @Operation(summary = "盘点任务统计")
    public ResponseBase inventoryCount(@RequestBody InventorySearchParam param) throws Exception {
        InventoryWorkInfoServiceImpl modelService = (InventoryWorkInfoServiceImpl) cmdbServiceManage.getModelService(InventoryWorkInfoServiceImpl.ID);
        Map<String, Integer> stringIntegerMap = modelService.inventoryCount(param);
        return setResultSuccess(stringIntegerMap);
    }


}
